import React, { useState, useEffect, useCallback } from 'react';
import {centerOfMass, polygon} from '@turf/turf';
import { Select, message } from 'antd';
import PropTypes from 'prop-types';
import axios from 'axios';
import { Scrollbars } from 'react-custom-scrollbars';
import classnames from 'classnames/bind';
import memo from '../../common/wrapMemo';

import { polygonColorMap } from '../../../constant/layers';

import api from '../../../api/index';
import LayerList from './LayerList';
import FeatureDetail from './FeatureDetail';
import Loading from '../../common/Loading';

import style from './Statistics.module.scss';

const cb = classnames.bind(style);

const { Option } = Select;
const { L } = window;
const { BASE_URL, WMS_URL } = window.CONFIG;

// let layerArr = [];
let pointLayer = null;
let polygonLayer = null;
// 行政区划features数据
// let adminData = [];
// 行政区划图层
let adminLayer = null;
// 行政区划子图层
let adminChildLayer = null;

// 面高亮图层
let polygonHighLayer = null;

// 面高亮样式配置
const highStyleOption = {
    weight: 2,
    opacity: 1,
    color: 'blue',
    fillOpacity: 0.2,
    fillColor: 'blue'
};

let center = [];
// const filterKeys = ['geom','geojson', 'gid', 'objectid', 'uid', 'shape_leng', 'shape_le_1', 'shape_area'];

const Statistics = memo((props) => {
    const { map, userInfo, setStatisticsShow, layerFields, featureNames, treeData } = props;
    const fields = layerFields.toJS();

    const [cities, setCities] = useState([]);
    const [secondCity, setSecondCity] = useState([]);
    const [town, setTown] = useState('');
    const [village, setVillage] = useState('');

    const [dataList, setDataList] = useState([]);           // 同统计列表数据
    const [layerDatas, setLayerDatas] = useState([]);       // 图层列表数据
    const [featureDatas, setFeatureDatas] = useState({});   // 要素详情数据
    const [curLayerCode, setCurLayerCode] = useState('');   // 当前操作图层code
    const [curLayerName, setCurLayerName] = useState('');   // 当前操作图层名称
    const [curUid, setCurUid] = useState('');
    const [areaUnits, setAreaUnits] = useState();
    const [visibleFields, setVisibleFields] = useState([]);

    const [layerListShow, setLayerListShow] = useState(false);
    const [featureDetailShow, setFeatureDetailShow] = useState(false);

    const [townLoading, setTownLoading] = useState(false);
    const [villageLoading, setVillageLoading] = useState(false);
    const [loading, setLoading] = useState(false);
    const [layerLoading, setLayerLoading] = useState(false);
    const [featureLoading, setFeatureLoading] = useState(false);
    const [total, setTotal] = useState(0);
    const [pageInfo, setPageInfo] = useState({page: 1,size: 20});  // 分页信息                 

    useEffect(async () => {
        addRegionLayer();
        // 行政区划查询
        setTownLoading(true);
        const params = {
            code: '330225000000'
        };

        api.search.queryAdmin(params)
            .then(res => {
                const {code, data = []} = res.data;
                if(code === 200) {
                    const adminData = generateAdminData(data);
                    setCities(adminData);
                }
            }).catch(err => {
                console.log(err);
            }).finally(() => {
                setTownLoading(false);
            })

        // 获取统计数据
        getStatisticsData();
    }, []);

    useEffect(() => {
        return () => {
            // 移除图斑
            removeOverLayer();
            removeAdminLayer();
            removeAdminChildLayer();
            removeHighLayer();
        };
    }, []);

    useEffect(() => {
        if(!featureDetailShow){
            removeHighLayer();
        }
    }, [featureDetailShow]);

    // 添加行政区划图层
    const addRegionLayer = () => {
        if(!map) return;
        // axios.get(`${BASE_URL}/lib/json/admin.json`).then(res => {
        //     if(res && res.data) {
        //         adminData = res.data.features;
                // adminLayer = L.geoJSON(res.data, {
                //     style: {
                //         "color": "#979797",
                //         "weight": 1,
                //         "opacity": 0.4,
                //         "fillOpacity": 0
                //     }
                // }).addTo(map);

                //http://82.156.55.198:8089/xsfarm/wms?service=WMS&version=1.1.0&request=GetMap&layers=xsfarm:admin&bbox=121.566956,28.85641,122.274972,29.662401&width=674&height=768&srs=EPSG:4326&styles=&format=application/openlayers

                // adminLayer = L.tileLayer.wms(
                //     `${WMS_URL}/xsfarm/wms?`,
                //     {
                //       layers: "xsfarm:admin", //需要加载的图层
                //       format: "image/png", //返回的数据格式
                //       transparent: true,
                //     }).addTo(map);

                // adminLayer = L.tileLayer(`${WMS_URL}/gwc/service/wmts?layer=xsfarm:admin&style=&tilematrixset=EPSG:900913&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/png&TileMatrix=EPSG:900913:{z}&TileCol={x}&TileRow={y}`, {
                //     minZoom: 2,
                //     maxZoom: 18,
                // }).addTo(map);

                adminLayer = L.tileLayer.wms(`${WMS_URL}/geoserver/xsxfarm/wms?`, {
                    layers: `xsxfarm:admin`,     
                    format: "image/png",    
                    transparent: true,
                }).addTo(map);
    };

    // 添加镇、村图层
    const addAdminLayer = (val, name) => {
        // 移除镇、村图层
        removeAdminChildLayer();

        let url = `${WMS_URL}/xsfarm/ows`;
        const layer = 'xsfarm:admin';
 
        const params = {
            service:'WFS',
            version:'1.1.0',
            request:'GetFeature',
            typeName:layer,
            outputFormat:'application/json',
            srsName:'EPSG:4326',
            CQL_FILTER:`${name} = '${val}'`
        };

        const url_str = url + L.Util.getParamString(params,url)
       
        axios({
            method: 'get', 
            url:url_str,
            responseType:'json'
        }).then(res=>{
            if(res.data) {
                adminChildLayer = L.geoJson(res.data,{
                    style: {
                        "color": "red",
                        "weight": 2,
                        "opacity": 0.8,
                        "fillOpacity": 0
                    }
                });
                adminChildLayer.addTo(map);
                map.fitBounds(adminChildLayer.getBounds());
            }
        })
    };

    // 获取统计数据
    const getStatisticsData = async (code = '330225000000') => {
        setLoading(true);
        const params = { 
            code
        };

        api.search.queryStatistics(params)
            .then((res) => {
                const {code, data} = res.data;
                if(code === 200){
                    setDataList(data);
                }
            }).catch(err => {
                console.log(err);
            }).finally(() => {
                setLoading(false);
            });
    };

    // 统计面板关闭
    const close = () => {
        setStatisticsShow(false);
    };

    // 乡镇切换事件
    const townChange = async (val, option) => {
        setTown(val);
        setVillage('');

        setVillageLoading(true);
        const params = {
            code: val,
        };

        api.search.queryAdmin(params).then((res) => {
            const {code, data} = res.data;
            if(code === 200) {
                const adminData = generateAdminData(data);
                setSecondCity(adminData);
                getStatisticsData(val);
            }
        }).catch((err) => {
            console.log(err);
        }).finally(() => {
            setVillageLoading(false);
        })
        
        // 添加镇、村图层
        addAdminLayer(option.key, "XZMC");
    };

    // 村切换事件
    const villageChange = (val, option) => {
        setVillage(val);
        getStatisticsData(val);
        setLayerListShow(false);
        // 添加镇、村图层
        addAdminLayer(option.key, "ZLDWMC");
    };

    // 移除镇、村图层
    const removeAdminChildLayer = () => {
        if(map && adminChildLayer){
            map.removeLayer(adminChildLayer);
            adminChildLayer = null;
        }
    };

    // 重置
    const reset = () => {
        setTown('');
        setVillage('');
        getStatisticsData();
        setLayerListShow(false);
        removeAdminChildLayer();
        if(map && adminLayer){
            // map.fitBounds(adminLayer.getBounds());
        }
    };

    // 组织行政区划数据
    const generateAdminData = (datas) => {
        const adminData = datas.map(data => {
            const {code, name} = data;
            return {
                label: code,
                value: name
            }
        });
        return adminData;
    };

    // 页码变化事件
    const pageChange = useCallback((pages) => {
        setPageInfo(pages);
        getLayerList(curLayerCode,curLayerName, pages);
    },[curLayerCode, curLayerName]);

    // 获取图层列表
    const getLayerList = (code, layerName, pageParam) => {
        
        code = code ? code : curLayerCode;
        layerName = layerName? layerName : curLayerName;
        pageParam = pageParam? pageParam : {...pageInfo};

        if(!code || !layerName) return;

        setLayerLoading(true);
        setLayerListShow(true);
        setFeatureDetailShow(false);
        setCurLayerCode(code);
        setCurLayerName(layerName);

        // 移除图斑
        removeOverLayer();

        const params = {
            code,
            regionCode: village? village : town ? town : '',
            pageParam,
            hasGeom: true
        };

        api.search.queryLayerList(params)
            .then((res) => {
                const {code, data} = res.data;
                if(code === 200){
                    const {count, result} = data;
                    setTotal(count);
                    setLayerDatas(result);
                    getJsonData(result, params.code);
                }
            }).catch(err => {
                console.log(err);
            }).finally(() => {
                setLayerLoading(false);
            })
    };

    // 获取图斑json数据
    const getJsonData = (datas, code) => {
        let pointFeatures = [];
        let polygonFeatures = [];
        datas.forEach((data) => {
            const { geojson, uid='' } = data;
            if(geojson) {
                const jsonData = JSON.parse(geojson);
                if(Object.keys(jsonData).length > 0 && uid){
                    const type = getType(jsonData.type);
                    const feature = {
                        type: 'Feature',
                        geometry: jsonData,
                        properties: {
                            code: code,
                            uid: uid,
                        }
                    };
                    if(type === 'point'){
                        pointFeatures.push(feature);
                    }else{
                        polygonFeatures.push(feature);
                    }
                }
            }
        });
        let pointJsonData = {
            type: 'FeatureCollection',
            crs: { type: 'name', properties: { name: 'EPSG:4490' } },
            features: pointFeatures,
        };

        let polygonJsonData = {
            type: 'FeatureCollection',
            crs: { type: 'name', properties: { name: 'EPSG:4490' } },
            features: polygonFeatures,
        };
        removeOverLayer();

        addPointLayer(pointJsonData);
        addPolygonLayer(polygonJsonData);
    };

    // 获取要素类型
    const getType = (jsonType) => {
        const type = jsonType.toLocaleLowerCase();
        if (type.includes('point')) {
            return 'point';
        }

        if (type.includes('line')) {
            return 'line';
        }

        if (type.startsWith('polygon')) {
            return 'polygon';
        }

        if(type.startsWith('multipolygon')){
            return 'MultiPolygon';
        }
    };

    // 添加点图层
    const addPointLayer = (pointJsonData) => {
        if (pointJsonData.features.length === 0) return;
        
        pointLayer = L.geoJSON(pointJsonData, {
            pointToLayer: function (feature, latlng) {
                return L.marker(latlng, {
                    icon: L.icon({
                        iconUrl: `${BASE_URL}/images/${feature.properties.code}.png`,
                        iconSize: [26, 26],
                        iconAnchor: [12, 12],
                    })
                });
            },
            onEachFeature: (feature, layer) => {
                layer.on({
                    click: (e) => {
                        // 要素详情展示
                        const { properties: {code, uid }} = e.target.feature;
                        getFeatureDetail(uid, code);
                    },
                });
            },
        });
        map.addLayer(pointLayer);
        map.fitBounds(pointLayer.getBounds());
    };

    // 获取面积单位
    const getUnits = (num) => {
        let areaUnits = {};
        let visibleFields = [];
        const cycle = (datas) => {
            datas.forEach(data => {
                const {code, children, fields} = data;
                if(code === num){
                    const {units={}, visible=''} = fields;
                    areaUnits = units;
                    visibleFields = visible.split(',');
                }else{
                    if(children.length > 0){
                        cycle(children);
                    }
                }
            })
        }

        cycle(treeData);
        setAreaUnits(areaUnits);
        setVisibleFields(visibleFields);
    };

    // 添加面图层
    const addPolygonLayer = (polygonJsonData) => {
        if (polygonJsonData.features.length === 0) return;

        polygonLayer = L.geoJSON(polygonJsonData, {
            style: function (feature) {
                return {
                    color: polygonColorMap[feature.properties.code] ? polygonColorMap[feature.properties.code] : 'red',
                    weight: 2,
                    opacity: 1,
                    fillColor: polygonColorMap[feature.properties.code] ? polygonColorMap[feature.properties.code] : 'red',
                    fillOpacity: 0.6,
                };
            },
            onEachFeature: (feature, layer) => {
                //对每个小块进行定义
                // layerArr.push(layer);
                layer.on({
                    //点击方法，变色
                    click: (e) => {
                        // layerArr.forEach((item) => {
                        //     polygonLayer && polygonLayer.resetStyle(item);
                        // });
                        // var layer = e.target;
                        
                        // layer.setStyle({
                        //     weight: 2,
                        //     opacity: 1,
                        //     color: 'blue',
                        //     fillOpacity: 0.6,
                        //     fillColor: 'blue',
                        // });

                        // 要素详情展示
                        const { properties: { code, uid }} = e.target.feature;
                        getFeatureDetail(uid, code);
                    },
                });
            },
        });

        map.addLayer(polygonLayer);
        map.fitBounds(polygonLayer.getBounds());
    };

    // 移除行政区划图层
    const removeAdminLayer = () => {
        if(map && adminLayer){
            map.removeLayer(adminLayer);
            adminLayer = null;
        }
    };

    // 移除图斑
    const removeOverLayer = () => {
        if (map) {
            if(pointLayer) {
                map.removeLayer(pointLayer);
                pointLayer = null;
            }
            if(polygonLayer){
                map.removeLayer(polygonLayer);
                polygonLayer = null;
            }
            // layerArr = [];
        }
    };

    // 要素定位
    const featureLocation = () => {
        // if(map && center[0] && center[1]){
        //     map.setView([center[1], center[0]]);
        // }

        if(map && polygonHighLayer){
            map.fitBounds(polygonHighLayer.getBounds());
        }
    };

    // 获取要素详情信息
    const getFeatureDetail = async (uid, code = '') => {
        setFeatureDetailShow(true);
        setFeatureLoading(true);
        setCurUid(uid);
        const layerCode = code? code : curLayerCode
        setCurLayerCode(layerCode);

        // 获取图斑详情
        const params = {
            uid,
            code: layerCode
        };
        
        // 获取面积单位 
        getUnits(layerCode);
        removeHighLayer();
        api.search.queryFeatureInfo(params)
            .then(res => {
                const {code, data} = res.data;
                if(code === 200){
                    const {geojson = '', ...resetData} = data;
                    if(geojson){
                        const geojsonData = JSON.parse(geojson);
                        const {type, coordinates} = geojsonData;
                        const featureType = getType(type);
                        if(featureType === 'point'){
                            center = coordinates;
                            polygonHighLayer = L.circle([center[1], center[0]], {radius: 10}).addTo(map);
                        }
                        if(featureType === 'polygon'){
                            const pointJson = centerOfMass(polygon(geojsonData['coordinates']));
                            center = pointJson.geometry.coordinates;
                            polygonHighLayer = L.geoJSON(geojsonData, highStyleOption).addTo(map);
                        }
                        if(featureType === 'MultiPolygon'){
                            const pointJson = centerOfMass(polygon(geojsonData['coordinates'][0]));
                            center = pointJson.geometry.coordinates;
                            polygonHighLayer = L.geoJSON(geojsonData, highStyleOption).addTo(map);
                        }
                    }
                    featureLocation();
                    setFeatureDatas(resetData);
                }
            }).catch(err => {
                console.log(err);
            }).finally(() => {
                setFeatureLoading(false);
            })
    };

    // 移除高亮
    const removeHighLayer = () => {
        // 移除高亮图层
        if(polygonHighLayer && map){
            map.removeLayer(polygonHighLayer);
            polygonHighLayer = null;
        }

        // 移除geojson高亮
        // Object.keys(layerArrMap).forEach(key => {
        //     layerArrMap[key].forEach(item => {
        //         renderLayerDatas[key] && renderLayerDatas[key].layer.resetStyle(item);
        //     });
        // });
    };

    // 删除要素
    const deleteFeature = (uid=curUid, code=curLayerCode) => {
        const params = {
            code, 
            uid
        };
        api.search.deleteFeature(params)
            .then(res => {
                const {code} = res.data;
                if(code === 200){
                    setFeatureDetailShow(false);
                    message.success('图斑删除成功！');
                    getStatisticsData();
                    getLayerList(curLayerCode);
                }else{
                    message.error('图斑删除失败！');
                }
            }).catch(err => {
                console.log(err);
                message.error('图斑删除失败！');
            });
    };

    // 保存编辑要素
    const saveFeature = async (val) => {
        const params = {
            operationContent:{
                items:{...val},
                itemsPrev:{},
                operation: 'update',
                uid: curUid
            },
            operationLayer: curLayerCode? curLayerCode : ''
        };

        console.log(curLayerName);
        
        api.search.saveFeature(params)
            .then(res => {
                const {code} = res.data;
                if(code === 200) {
                    getStatisticsData();
                    getLayerList(curLayerCode);
                    message.success('提交成功！');
                }else{
                    message.error('提交失败！');
                }
            }).catch(() => {
                message.error('提交失败！');
            });
    };

    // 关闭图层列表面板
    const closeLayerListPanel = () => {
        setLayerListShow(false);
        setFeatureDetailShow(false);
    };

    const itemClick = (data) => {
        setPageInfo({page: 1,size: 20});
        const {code, layerName} = data;
        setCurLayerCode(code);
        setCurLayerName(layerName);
        getLayerList(code, layerName, {page: 1,size: 20})
    };

    // 统计数据列表内容
    const statisticsItem = dataList.map((data, index) => {
        const { layerName, count, area, code, unit } = data;
        const itemClassName = cb({
            item: true,
            itemSelected: curLayerCode === code,
        });
        return (
            <div className={itemClassName} key={index} onClick={() => itemClick(data)}>
                <span>{layerName}</span>
                <span>{count}</span>
                <span>{`${Math.round(area)} (${unit})`}</span>
            </div>
        );
    });

    // 乡镇数据options
    const getCityOptions = cities.map((city) => {
        return (
            <Option value={city.label} key={city.value}>
                {city.value}
            </Option>
        );
    });

    // 村数据options
    const getSecondCityOptions = secondCity.map((city) => {
        return (
            <Option value={city.label} key={city.value}>
                {city.value}
            </Option>
        );
    });

    return (
        <>
            <div className={style.statistics}>
                <div className={style.header}>
                    <span>数据统计</span>
                    <i className="iconfont icon-close" onClick={close}></i>
                </div>
                <div className={style.filter}>
                    <Select
                        placeholder="请选择镇"
                        style={{ width: 128, marginRight: 8 }}
                        onChange={townChange}
                        value={town}
                        loading={townLoading}
                    >
                        {getCityOptions}
                    </Select>
                    <Select
                        placeholder="请选择村"
                        style={{ width: 128 }}
                        onChange={villageChange}
                        value={village}
                        loading={villageLoading}
                    >
                        {getSecondCityOptions}
                    </Select>
                    <span className={style.reset} onClick={reset}>
                        重置
                    </span>
                </div>
                <div className={style.title}>
                    <span>象山县</span>
                </div>
                <div className={style.dataList}>
                    <div className={style.dataHeader}>
                        <span>图层名称</span>
                        <span>图斑个数</span>
                        <span>面积</span>
                    </div>
                    <div className={style.dataContent}>
                        {loading ? (
                            <Loading />
                        ) : (
                            <Scrollbars
                                autoHeight
                                autoHeightMin={220}
                                autoHeightMax={`calc(100vh - 330px)`}
                            >
                                {statisticsItem}
                            </Scrollbars>
                        )}
                    </div>
                </div>
            </div>
            {layerListShow && (
                <LayerList
                    left={384}
                    total={total}
                    pageChange={pageChange}
                    layerDatas={layerDatas}
                    curLayerCode={curLayerCode}
                    featureNames={featureNames}
                    loading={layerLoading}
                    pageInfo={pageInfo}
                    setPageInfo={setPageInfo}
                    getFeatureDetail={getFeatureDetail}
                    closeLayerListPanel={closeLayerListPanel}
                />
            )}
            {featureDetailShow && (
                <FeatureDetail
                    userInfo={userInfo}
                    featureLoading={featureLoading}
                    fields={fields}
                    visibleFields={visibleFields}
                    areaUnits={areaUnits}
                    featureDatas={featureDatas}
                    layerFields={layerFields}
                    deleteFeature={deleteFeature}
                    featureLocation={featureLocation}
                    saveFeature={saveFeature}
                    setFeatureDetailShow={setFeatureDetailShow}
                />
            )}
        </>
    );
});

Statistics.propTypes = {
    map: PropTypes.object,
    userInfo: PropTypes.object,
    featureNames: PropTypes.object,
    setStatisticsShow: PropTypes.func,
    layerFields: PropTypes.object,
};

export default Statistics;
